package goods

import (
	"context"
	"encoding/json"
	"gorm.io/gorm"
	"net/url"
	"regexp"
	"sale-admin/config/mysql"
	"sale-admin/internal/app/grpc/client"
	"sale-admin/internal/app/grpc/protoc/devicec"
	"sale-admin/internal/app/grpc/protoc/system_admin"
	"sale-admin/internal/app/web/schema"
	"sale-admin/internal/app/web/service/common"
	"sale-admin/internal/dal"
	"sale-admin/internal/dao"
	"sale-admin/internal/define"
	"sale-admin/internal/models"
	"strconv"
	"strings"
	"time"
	"unicode/utf8"

	"192.168.1.75/go-pkg/errorx"
	"192.168.1.75/go-pkg/helper"
	"192.168.1.75/go-pkg/logx"
	"github.com/PuerkitoBio/goquery"
	"github.com/golang-module/carbon/v2"
	"github.com/samber/lo"
)

const (
	REAL_GOODS_TYPE         = 1 // 实物商品
	GUIDE_GOODS_TYPE        = 2 // 导流商品
	VIRTUAL_GOODS_TYPE      = 3 // 虚拟商品
	POINTS_GOODS_TYPE       = 4 // 积分商品
	COUPON_GOODS_TYPE       = 5 // 优惠码商品
	ZERO_GOODS_TYPE         = 6 // 0元购商品
	GIVE_GOODS_TYPE         = 7 // 活动赠品
	ONLINE_EVENT_GOODS_TYPE = 8 // 线上活动商品
)

type GoodsService struct{}

func HandlerGoodsDetail(str string) string {

	SystemAdminClient, clientErr := client.GetSystemAdminClient()
	if clientErr != nil {
		return ""
	}
	reader := strings.NewReader(str)
	doc, err := goquery.NewDocumentFromReader(reader)
	if err == nil {
		doc.Find("img").Each(func(i int, s *goquery.Selection) {
			src, _ := s.Attr("src")
			URL, _ := url.Parse(src)
			match, matchErr := regexp.MatchString("^(/file/sale-admin/).*(/temp/).*$", URL.Path)
			if matchErr == nil && match {
				//文件确认
				var req system_admin.ConfirmFileReq
				req.FileUrl = URL.Path
				res, err1 := SystemAdminClient.ConfirmFile(context.Background(), &req)
				if err1 != nil && res.Code != 0 {
					logx.Error(context.Background(), "goods confirm file error", logx.Any("res", res), logx.Any("err", err.Error()))
					return
				}
				ImagePath := URL.Scheme + "://" + URL.Host + res.FileUrl
				s.SetAttr("src", ImagePath) //修改标签的内容
			}
		})
	}
	newGoods, _ := goquery.OuterHtml(doc.Selection)
	returnHtml := strings.TrimSuffix(strings.TrimPrefix(newGoods, "<html><head></head><body>"), "</body></html>")
	return returnHtml
}

func (gs GoodsService) SaveGoodsInfo(ctx context.Context, merchantID, goodsID string, goodsType int,
	goodsName1, goodsName2, classID string, price, price1 float64, goodsImage,
	goodsCode, goodsDetail, showTag, spring string, isAuth int,
	ExternalProductID, goodsVoice string, deductionLimit, Points float64, PointsSupport int,
	codeImage, voiceKeywords string, recommend int, recommendImage, adImage, cornerLabelId, tagCode string, PurchaseType int,
	reviewPoints int, ExpressFeeTemplate string,
	goodsGuideType define.GoodsGuideType, goodsGuideURL string, shareCodeType define.ShareCodeType, shareCode string, goodsGuideNotice string,
) (err error) {
	logx.Info(ctx, "Express0801 GoodsService.SaveGoodsInfo", logx.Any("goodsID", goodsID), logx.Any("goodsType", goodsType),
		logx.Any("ExternalProductID", ExternalProductID), logx.Any("ExpressFeeTemplate", ExpressFeeTemplate))
	ConfirmGoodsImage := true
	ConfirmRecommendImage := true
	ConfirmCodeImage := true
	ConfirmAdImage := true
	ConfirmGoodsGuideImage := true //导流图片确认

	db := mysql.NewDB()
	if strings.TrimSpace(goodsName1) == "" {
		err = errorx.New("商品名称不能为空", -1)
		return
	}
	goodsName1 = strings.TrimSpace(goodsName1)
	if utf8.RuneCountInString(goodsName1) > 255 {
		err = errorx.New("商品名称不能超过255个字符", -1)
		return
	}
	sameNameCount, _ := dao.Goods{}.SameNameExist(ctx, db, merchantID, goodsName1, goodsID)
	if sameNameCount > 0 {
		err = errorx.New("商品名称已经存在", -1)
		return
	}
	goodsName2 = strings.TrimSpace(goodsName2)
	if utf8.RuneCountInString(goodsName2) > 255 {
		err = errorx.New("英文名称不能超过255个字符", -1)
		return
	}
	if goodsCode != "" {
		regRes, _ := regexp.MatchString(define.REGEXP_EAN_13, goodsCode)
		if !regRes {
			err = errorx.New("国标编码格式错误", -1)
			return
		}
	}
	if tagCode != "" {
		if utf8.RuneCountInString(tagCode) > 50 {
			err = errorx.New("商品编码不能超过50字符", -1)
			return
		}
	}
	if goodsType < 1 || goodsType > 8 {
		err = errorx.New("商品类型错误", -1)
		return
	}
	if classID == "" {
		classID = "0"
	}
	if goodsType == REAL_GOODS_TYPE {
		if price <= 0 {
			err = errorx.New("商品价格必须大于0", -1)
			return
		}
		if deductionLimit < 0 {
			err = errorx.New("抵额上限不能小于0", -1)
			return
		}
		if deductionLimit > price {
			err = errorx.New("抵额上限不能大于商品价格", -1)
			return
		}
	} else if goodsType == COUPON_GOODS_TYPE {
		if price <= 0 {
			err = errorx.New("商品价格必须大于0", -1)
			return
		}
		if deductionLimit < 0 {
			err = errorx.New("抵额上限不能小于0", -1)
			return
		}
		if deductionLimit > price {
			err = errorx.New("抵额上限不能大于商品价格", -1)
			return
		}
	} else if goodsType == ZERO_GOODS_TYPE {
		if deductionLimit < 0 {
			err = errorx.New("抵额上限不能小于0", -1)
			return
		}
		if deductionLimit > price {
			err = errorx.New("抵额上限不能大于商品价格", -1)
			return
		}
	} else if goodsType == POINTS_GOODS_TYPE {
		if price < 0 {
			err = errorx.New("商品价格不能小于0", -1)
			return
		}
		if PointsSupport != 0 && PointsSupport != 1 {
			err = errorx.New("是否支持现金抵积分类型错误", -1)
			return
		}
		if Points < 1 || Points > 999999 {
			err = errorx.New("积分允许输入区间为1~999999", -1)
			return
		}
	} else if goodsType == GIVE_GOODS_TYPE {
		if price < 0 {
			err = errorx.New("商品价格不能小于0", -1)
			return
		}
		if PointsSupport != 0 && PointsSupport != 1 {
			err = errorx.New("是否支持现金抵积分类型错误", -1)
			return
		}
	}

	if err := gs.VerifyGoodsGuideParams(goodsGuideType, goodsGuideURL, shareCodeType, shareCode); err != nil {
		logx.Error(ctx, "VerifyGoodsGuideParams err:", logx.Any("goodsGuideType", goodsGuideType), logx.Any("goodsGuideURL", goodsGuideURL), logx.Any("shareCodeType", shareCodeType), logx.Any("shareCode", shareCode))
		return err
	}

	// 导流商品使用兑换码支付
	var useRC uint = 0
	if goodsType == GUIDE_GOODS_TYPE {
		useRC = 1
	}
	
	if goodsID == "" { // 新增
		var nameExist int64
		db.Model(&models.MaGoodsInfo{}).
			Where("goods_name1 = ? and deleted = 0", goodsName1).
			Where("merchant_id = ?", merchantID).
			Count(&nameExist)
		if nameExist > 0 {
			err = errorx.New("商品名称已经存在", -1)
			return
		}

		var InsertData models.MaGoodsInfo
		InsertData.ID = merchantID // 商户ID
		InsertData.MerchantID = merchantID
		InsertData.GoodsType = goodsType
		InsertData.ClassID = classID
		InsertData.GoodsName1 = goodsName1
		InsertData.GoodsName2 = goodsName2
		InsertData.GoodsCode = goodsCode
		InsertData.Price = price
		InsertData.Price1 = price1
		InsertData.Spring = spring
		InsertData.IsAuth = isAuth
		InsertData.ShowTag = showTag
		InsertData.GoodsDetail = HandlerGoodsDetail(goodsDetail)
		InsertData.GoodsVoice = goodsVoice
		InsertData.Points = Points
		InsertData.PointsSupport = PointsSupport
		InsertData.VoiceKeywords = voiceKeywords // 语音关键词
		InsertData.Recommend = recommend         // 商品首页推荐
		InsertData.ExternalProductID = ExternalProductID
		InsertData.DeductionLimit = deductionLimit
		InsertData.CornerLabelID = cornerLabelId // 角标ID
		InsertData.UseRC = useRC                 //导流商品必须为1
		InsertData.TagCode = tagCode
		InsertData.PurchaseType = PurchaseType
		InsertData.ReviewPoints = reviewPoints
		InsertData.ExpressFeeTemplate = ExpressFeeTemplate

		//导流配置字段
		InsertData.GoodsGuideType = goodsGuideType
		//InsertData.GoodsGuideURL = goodsGuideURL //在下面确认图片后再设置
		InsertData.ShareCodeType = shareCodeType
		InsertData.ShareCode = shareCode
		InsertData.GoodsGuideNotice = goodsGuideNotice

		err = db.Model(&models.MaGoodsInfo{}).Create(&InsertData).Error
		if err != nil {
			err = errorx.New("操作失败", -1)
			return
		}
		goodsID = InsertData.GoodsID
		
		if goodsImage == "" {
			ConfirmGoodsImage = false
		}
		if codeImage == "" {
			ConfirmCodeImage = false
		}
		if adImage == "" {
			ConfirmAdImage = false
		}
		if recommendImage == "" {
			ConfirmRecommendImage = false
		}

		if goodsGuideURL == "" {
			ConfirmGoodsGuideImage = false
		}
	} else {
		if !(dao.Goods{}.HasAuth(ctx, dal.Q, merchantID, goodsID)) {
			return errorx.New("无权限", -1)
		}
		var GoodsInfo models.MaGoodsInfo
		rowsAffected := db.Model(&models.MaGoodsInfo{}).
			Where("goods_id = ? AND deleted = 0 AND goods_type = ?", goodsID, goodsType).
			Take(&GoodsInfo).
			RowsAffected
		if rowsAffected <= 0 {
			err = errorx.New("商品信息不存在", -1)
			return
		}
		var nameExist int64
		db.Model(&models.MaGoodsInfo{}).
			Where("goods_name1 = ? and goods_id != ? and deleted = 0", goodsName1, goodsID).
			Where("merchant_id = ?", merchantID).
			Count(&nameExist)
		if nameExist > 0 {
			err = errorx.New("商品名称已经存在", -1)
			return
		}
		if goodsImage == "" || GoodsInfo.GoodsImage == goodsImage {
			ConfirmGoodsImage = false
		}
		if codeImage == "" || GoodsInfo.CodeImage == codeImage {
			ConfirmCodeImage = false
		}
		if adImage == "" || GoodsInfo.AdImage == adImage {
			ConfirmAdImage = false
		}
		if recommendImage == "" || GoodsInfo.RecommendImage == recommendImage {
			ConfirmRecommendImage = false
		}

		if goodsGuideURL == "" || GoodsInfo.GoodsGuideURL == goodsGuideURL {
			ConfirmGoodsGuideImage = false
		}

		db := mysql.NewDB()
		db.Transaction(func(tx *gorm.DB) error {

			oldGoodsInfo, geterr := dao.Goods{}.Detail(ctx, dal.Q, goodsID)
			if geterr != nil {
				logx.Error(ctx, "save goodsInfo update error", logx.Any("err", geterr))
				err = errorx.New("操作失败", -1)
				return geterr
			}

			// 编辑商品信息
			updateErr := db.Model(&models.MaGoodsInfo{}).
				Where("goods_id = ? and deleted = 0", goodsID).
				Updates(map[string]interface{}{
					"class_id":             classID,
					"goods_name1":          goodsName1,
					"goods_name2":          goodsName2,
					"goods_code":           goodsCode,
					"price":                price,
					"price1":               price1,
					"spring":               spring,
					"is_auth":              isAuth,
					"show_tag":             showTag,
					"goods_detail":         HandlerGoodsDetail(goodsDetail),
					"goods_voice":          goodsVoice,
					"points":               Points,
					"points_support":       PointsSupport,
					"voice_keywords":       voiceKeywords,
					"recommend":            recommend,
					"external_product_id":  ExternalProductID,
					"deduction_limit":      deductionLimit,
					"corner_label_id":      cornerLabelId,
					"use_rc":               useRC, // 导流商品必须为1,其他为0
					"tag_code":             tagCode,
					"purchase_type":        PurchaseType,
					"review_points":        reviewPoints,
					"express_fee_template": ExpressFeeTemplate,
					//导流配置字段
					"goods_guide_type": goodsGuideType,
					//"goods_guide_url":    goodsGuideURL, 在下面确认图片时再设置
					"share_code_type":    shareCodeType,
					"share_code":         shareCode,
					"goods_guide_notice": goodsGuideNotice,
				}).Error
			if updateErr != nil {
				logx.Error(ctx, "save goodsInfo update error", logx.Any("err", updateErr))
				err = errorx.New("操作失败", -1)
				return updateErr
			}

			newGoodsInfo := &models.MaGoodsInfo{
				GoodsID:            goodsID,
				ClassID:            classID,
				GoodsName1:         goodsName1,
				GoodsName2:         goodsName2,
				GoodsCode:          goodsCode,
				Price:              price,
				Price1:             price1,
				Spring:             spring,
				IsAuth:             isAuth,
				ShowTag:            showTag,
				GoodsDetail:        HandlerGoodsDetail(goodsDetail),
				GoodsVoice:         goodsVoice,
				Points:             Points,
				PointsSupport:      PointsSupport,
				VoiceKeywords:      voiceKeywords,
				Recommend:          recommend,
				ExternalProductID:  ExternalProductID,
				DeductionLimit:     deductionLimit,
				CornerLabelID:      cornerLabelId,
				UseRC:              useRC,
				TagCode:            tagCode,
				PurchaseType:       PurchaseType,
				ReviewPoints:       reviewPoints,
				ExpressFeeTemplate: ExpressFeeTemplate,

				GoodsGuideType:   goodsGuideType,
				GoodsGuideURL:    goodsGuideURL,
				ShareCodeType:    shareCodeType,
				ShareCode:        shareCode,
				GoodsGuideNotice: goodsGuideNotice,
			}

			inserterr := GoodsLogService{}.InsertLog(ctx, tx, merchantID, oldGoodsInfo, newGoodsInfo)
			if inserterr != nil {
				logx.Error(ctx, "save goodsInfo update error", logx.Any("err", inserterr))
				err = errorx.New("操作失败", -1)
				return inserterr
			}

			return nil
		})

	}

	SystemAdminClient, clientErr := client.GetSystemAdminClient()
	if clientErr != nil {
		err = clientErr
		return
	}

	//图片确认
	if ConfirmGoodsImage { // 商品图片
		var req system_admin.ConfirmFileReq
		req.FileUrl = goodsImage
		res, err1 := SystemAdminClient.ConfirmFile(ctx, &req)
		if err1 != nil || res.Code != 0 {
			logx.Error(ctx, "save goodsInfo confirm file error", logx.Any("res", res), logx.Any("err", err1))
		} else {
			//保存图片
			db.Model(&models.MaGoodsInfo{}).
				Where("goods_id = ? and deleted = 0", goodsID).
				UpdateColumn("goods_image", res.FileUrl)
		}
	}
	if ConfirmCodeImage { // 界面引导图
		var req system_admin.ConfirmFileReq
		req.FileUrl = codeImage
		res, err1 := SystemAdminClient.ConfirmFile(ctx, &req)
		if err1 != nil || res.Code != 0 {
			logx.Error(ctx, "save goodsInfo confirm file error", logx.Any("res", res), logx.Any("err", err1))
		} else {
			//保存图片
			db.Model(&models.MaGoodsInfo{}).
				Where("goods_id = ? and deleted = 0", goodsID).
				UpdateColumn("code_image", res.FileUrl)
		}
	}
	if ConfirmRecommendImage { // 推荐图
		var req system_admin.ConfirmFileReq
		req.FileUrl = recommendImage
		res, err1 := SystemAdminClient.ConfirmFile(ctx, &req)
		if err1 != nil || res.Code != 0 {
			logx.Error(ctx, "save goodsInfo confirm file error", logx.Any("res", res), logx.Any("err", err1))
		} else {
			// 保存图片
			db.Model(&models.MaGoodsInfo{}).
				Where("goods_id = ? and deleted = 0", goodsID).
				UpdateColumn("recommend_image", res.FileUrl)
		}
	}
	if ConfirmAdImage { // 商品广告推荐图
		var req system_admin.ConfirmFileReq
		req.FileUrl = adImage
		res, err1 := SystemAdminClient.ConfirmFile(ctx, &req)
		if err1 != nil || res.Code != 0 {
			logx.Error(ctx, "save goodsInfo confirm file error", logx.Any("res", res), logx.Any("err", err1))
		} else {
			// 保存图片
			db.Model(&models.MaGoodsInfo{}).
				Where("goods_id = ? and deleted = 0", goodsID).
				UpdateColumn("ad_image", res.FileUrl)
		}
	}

	if ConfirmGoodsGuideImage == true {
		var req system_admin.ConfirmFileReq
		req.FileUrl = goodsGuideURL
		res, err1 := SystemAdminClient.ConfirmFile(ctx, &req)
		if err1 != nil || res.Code != 0 {
			logx.Error(ctx, "save GoodsGuideImage confirm file error", logx.Any("res", res), logx.Any("err", err1))
			return errorx.New("保存图片失败", -1)
		}

		// 保存图片
		db.Model(&models.MaGoodsInfo{}).
			Where("goods_id = ? and deleted = 0", goodsID).
			UpdateColumn("goods_guide_url", res.FileUrl)
	}
	return
}

// GoodsDetail 获取商品详情
func (gs GoodsService) GoodsDetail(ctx context.Context, merchantID string, goodsID string) (data interface{}, err error) {
	db := mysql.NewDB()
	var GoodsInfo struct {
		models.MaGoodsInfo
		ClassName string `gorm:"column:class_name" json:"class_name"`
	}
	db.Table(models.MaGoodsInfo{}.TableName()+" as g").
		Joins("left join "+models.MaGoodsClass{}.TableName()+" as class on g.class_id = class.class_id").
		Where("g.goods_id = ? and g.deleted = 0", goodsID).
		Select("g.*,class.class_name").
		Order("g.goods_id desc").
		Take(&GoodsInfo)
	logx.Info(ctx, "Express0801 GoodsService.GoodsDetail", logx.Any("goodsID", goodsID),
		logx.Any("GoodsInfo", GoodsInfo))

	return GoodsInfo, nil
}

// 获取活动商品[单或多个] --- 一个机器可以拥有多个规则，一个规则可以包含多个商品，一个商品可以关联一组优惠商品
func (gs GoodsService) GetActivityGoodsOfMulti(
	ctx context.Context, merchantID, salesID,
	id string, // 活动ID，不传获取所有，因为只某个机器下的规则，所以不做分页
) (
	res []schema.AllGoodsActivityDataDetail,
	err error,
) {

	// --- 开始查询 ---
	db := mysql.NewDB()
	tx := db.Table(models.MaGoodsActivity{}.TableName() + " as a1").
		Joins("LEFT JOIN " + models.MaGoodsActivityDetail{}.TableName() + " as a2 ON a1.id = a2.activity_id")
	if id != "" {
		tx.Where("a1.id = ?", id)
	}
	tx.Where("a1.sales_id = ?", salesID).
		Select("a1.*,a2.*").
		Find(&res)

	// 根据时间比较是否开始还是进行中或者已经结束
	for k, v := range res {
		endtime, _ := strconv.Atoi(v.EndTime)
		starttime, _ := strconv.Atoi(v.StartTime)
		if time.Now().Unix() < int64(endtime) && time.Now().Unix() > int64(starttime) { // 进行中
			v.Status = "2"
		}
		if time.Now().Unix() < int64(starttime) { // 未开始
			v.Status = "1"
		}
		if time.Now().Unix() > int64(endtime) { // 已结束
			v.Status = "3"
		}
		res[k] = v
	}

	// 获取当前机器可用的商品ID
	var goodsRes = []models.MaRobotSalesInfo{}
	db.Model(&models.MaRobotSalesInfo{}).
		Where("sales_id = ?", salesID).
		Where("container_status = ?", 1). // 已上架商品
		Group("goods_id").
		Order("sort desc").
		Find(&goodsRes)
	var sliceGoodsID = []string{}
	for _, v := range goodsRes {
		sliceGoodsID = append(sliceGoodsID, v.GoodsID)
	}

	// 定义返回的空数组
	var new_res = []schema.AllGoodsActivityDataDetail{}
	for _, v := range res {

		// 判断商品是否有效
		if lo.Contains(sliceGoodsID, v.GoodsID) {

			// 过滤第二层优惠商品
			// json_decode 解析原的数据
			var countData []schema.MultiDiscountGoodsTwo
			json.Unmarshal([]byte(v.MultiDiscountGoods), &countData)
			// 装筛选通过的数据
			var countData1 []schema.MultiDiscountGoodsTwo
			for _, discountInfo := range countData {
				// 判断商品是否有效
				if lo.Contains(sliceGoodsID, discountInfo.GoodsID) {
					// 重新赋值MultiDiscountGoods
					var item1 schema.MultiDiscountGoodsTwo
					item1.GoodsID = discountInfo.GoodsID
					item1.Discount = discountInfo.Discount
					item1.ExchangePrice = discountInfo.ExchangePrice
					goodsInfo, err := dao.Goods{}.Detail(ctx, dal.Q, discountInfo.GoodsID)
					if err == nil && goodsInfo != nil {
						item1.GoodsName = goodsInfo.GoodsName1
						item1.GoodsImage = goodsInfo.GoodsImage
						item1.GoodsPrice = goodsInfo.Price
					}
					countData1 = append(countData1, item1)
				}
			}
			if len(countData1) > 0 {
				// json_encode
				jsonBytes, _ := json.Marshal(countData1)
				v.MultiDiscountGoods = string(jsonBytes)
			}
			// 有效则重新赋值 --- 其中第二层的过滤需要判断
			new_res = append(new_res, v)
		}

	}

	// 重新组装，把活动ID相同的归类为一组
	var myarr1 = make(map[string][]schema.GoodsActivityDataNew)
	var myarr2 = make(map[string]schema.AllGoodsActivityDataDetail)
	for _, v := range new_res {
		var item1 schema.GoodsActivityDataNew
		// 对同一机器下相同活动ID的商品进行归类
		item1.Type = v.Type
		item1.AssocGoodsID = v.GoodsID
		goodsInfo, err := dao.Goods{}.Detail(ctx, dal.Q, v.GoodsID)
		if err == nil && goodsInfo != nil {
			item1.GoodsName = goodsInfo.GoodsName1
			item1.GoodsImage = goodsInfo.GoodsImage
		}
		if v.MultiDiscountGoods == "null" {
			item1.DiscountGoodsInfo = "[]"
		} else {
			item1.DiscountGoodsInfo = v.MultiDiscountGoods
		}
		myarr1[v.ActivityID] = append(myarr1[v.ActivityID], item1)
		myarr2[v.ActivityID] = v
	}

	var result = []schema.AllGoodsActivityDataDetail{}
	for _, v := range myarr2 {
		if _, ok := myarr1[v.ActivityID]; ok {
			v.ActivityData = myarr1[v.ActivityID]
			result = append(result, v)
		}
	}
	return result, nil
}

// 删除活动商品
func (gs GoodsService) DelActivityGoodsOfMulti(ctx context.Context, merchantID, activity_id, salesID string) (err error) {
	// 删除活动主表
	db := mysql.NewDB()
	db.Model(&models.MaGoodsActivity{}).
		Where("id = ?", activity_id).
		Delete(&models.MaGoodsActivity{})
	// 删除详情表
	db.Model(&models.MaGoodsActivityDetail{}).
		Where("activity_id = ?", activity_id).
		Delete(&models.MaGoodsActivityDetail{})
	return err
}

// SyncActivityGoods 当前机器的商品活动，同步到其他机器
func (gs GoodsService) SyncActivityGoods(ctx context.Context, merchantID, // 当前的商户ID
	NowRobotName,                                                         // 当前机器的名称
	NowActivityID,                                                        // 当前机器的活动规则ID
	SyncRobotName string, // 要同步的机器名称,多个时逗号隔开
) (
	data interface{},
	AsyncCount int64,
	err error,
) {

	db := mysql.NewDB()

	// ===== 获取当前机器的信息，及活动的信息（活动使用sales_id进行获取） =======
	var robotInfo models.MaRobot
	tx := db.Table(models.MaRobot{}.TableName() + " as r")
	tx.Where("r.robot_name = ?", NowRobotName).Take(&robotInfo)

	// 活动及活动详情表
	var activityInfo []schema.AllGoodsActivityDataDetail
	db.Table(models.MaGoodsActivity{}.TableName()+" as a").
		Joins("LEFT JOIN "+models.MaGoodsActivityDetail{}.TableName()+" AS d ON a.id = d.activity_id").
		Where("a.sales_id = ?", robotInfo.SalesID).
		Where("a.id = ?", NowActivityID).
		Where("a.end_time >= ?", time.Now().Unix()).
		Select("a.*", "d.*").
		Find(&activityInfo) // 一个规则可以对应多组商品

	// 活动已失效或者过期
	if len(activityInfo) == 0 {
		err = errorx.New("活动已失效或者过期", -1)
		return
	}
	// -------------- 对需要同步规则的机器进行操作，对要同步的机器循环操纵。一台一台判断是否符合商品条件 --------------
	if SyncRobotName == "" {
		err = errorx.New("需要同步的机器信息不能为空", -1)
		return
	}
	// 查询要同步的机器的信息 --- 一次查询所有机器的商品ID
	var syncRobotInfo = []models.MaRobotSalesInfo{}
	db.Table(models.MaRobot{}.TableName()+" as r").
		Where("r.robot_name in (?)", strings.Split(SyncRobotName, ",")).
		Joins("LEFT JOIN " + models.MaRobotSalesInfo{}.TableName() + " AS rs ON r.sales_id = rs.sales_id").
		Select("rs.*").
		Find(&syncRobotInfo)
	if len(syncRobotInfo) == 0 {
		err = errorx.New("机器信息不存在", -1)
		return
	}

	// 这个是同步的机器的信息，允许同步多台机器。想要达到效果：每个机器对应一组商品ID
	var AllSyncRobotGoodsId = make(map[string][]string)
	for _, v := range syncRobotInfo {
		// 获取每个机器的补货列表的所有商品
		AllSyncRobotGoodsId[v.SalesID] = append(AllSyncRobotGoodsId[v.SalesID], v.GoodsID)
	}

	// 开始添加了。
	// 判断关联商品
	// OneRobotGoodsArr 指的是：一组机器的商品ID
	for k, OneRobotGoodsArr := range AllSyncRobotGoodsId {
		// var item = []schema.AllGoodsActivityDataDetail{}
		// 用于返回同步成功的机器的数量
		var AsyncCountDetail int64 = 0
		for _, v := range activityInfo {
			// 开始添加规则
			// 第一层校验成功（当前规则的关联商品ID, 能再机器的补货商品中找到）
			if lo.Contains(OneRobotGoodsArr, v.GoodsID) {
				// 判断第二层是否成功？
				var discountGoodsID []schema.MultiDiscountGoodsTwo // 当前规则的所有可以优惠ID
				var arr []schema.MultiDiscountGoodsTwo
				json.Unmarshal([]byte(v.MultiDiscountGoods), &arr)
				// 多个json字符串，所以要循环
				// 罗列优惠商品的GoodsID
				discountGoodsID = append(discountGoodsID, arr...)
				var myDiscountArrInfo []schema.MultiDiscountGoodsTwo
				if len(discountGoodsID) > 0 {
					for _, v := range discountGoodsID {
						if lo.Contains(OneRobotGoodsArr, v.GoodsID) {
							myDiscountArrInfo = append(myDiscountArrInfo, v)
						}
					}

					// 2、写入主活动表
					// 判断主表是否存在该活动
					var activityCount int64
					var myactivityInfo models.MaGoodsActivity
					db.Model(&models.MaGoodsActivity{}).
						Where("sales_id = ?", k).
						Where("activity_ = ?", k).
						Take(&myactivityInfo).
						Count(&activityCount)
					var insertID string
					if activityCount == 0 {
						var InsertData models.MaGoodsActivity
						InsertData.ActivityName = v.ActivityName
						InsertData.StartTime = v.StartTime
						InsertData.EndTime = v.EndTime
						InsertData.SalesID = k
						InsertData.Status = "1"
						err = db.Model(&models.MaGoodsActivity{}).Create(&InsertData).Error
						if err != nil {
							err = errorx.New("操作失败", -1)
							return
						}
						AsyncCountDetail += 1
						insertID = InsertData.ID
					} else {
						insertID = myactivityInfo.ID
					}

					// 1、写入活动详情表
					var InsertDetailData models.MaGoodsActivityDetail
					// 转成json字符串
					InsertDetailData.GoodsID = v.GoodsID // 商品ID
					jsonDiscountGoodsInfo, _ := json.Marshal(myDiscountArrInfo)
					InsertDetailData.MultiDiscountGoods = string(jsonDiscountGoodsInfo) // json字符串
					InsertDetailData.SalesID = k                                        // 机器ID
					InsertDetailData.ActivityID = insertID                              // 活动ID
					InsertDetailData.Type = v.Type                                      // Type 1 折扣 2换购
					//
					err = db.Model(&models.MaGoodsActivityDetail{}).Create(&InsertDetailData).Error
					if err != nil {
						err = errorx.New("操作失败", -1)
						return
					}

				}
			}
		}
		if AsyncCountDetail > 0 {
			AsyncCount += 1
		}
	}
	return
}

// 设置商品活动
func (gs GoodsService) SaveActivityGoodsOfMulti(
	ctx context.Context, merchantID, name, salesID, start_time, end_time, id string,
	data []schema.GoodsActivityData,
) (
	err error,
) {
	db := mysql.NewDB()
	// 新增
	if id == "" {
		var InsertData models.MaGoodsActivity
		// 活动名称
		InsertData.ActivityName = name
		InsertData.SalesID = salesID
		InsertData.Status = "1" // 1 待开始 2进行中 3已结束

		// 只能添加今天以后的数据
		a := carbon.Parse(start_time).Timestamp()
		b := carbon.Parse(end_time).Timestamp()
		InsertData.StartTime = strconv.Itoa(int(a))
		InsertData.EndTime = strconv.Itoa(int(b))

		// 写入商品活动表
		err = db.Model(&models.MaGoodsActivity{}).Create(&InsertData).Error
		insertID := ""
		if err != nil {
			err = errorx.New("操作失败", -1)
			return
		}
		insertID = InsertData.ID
		// 商品活动详情表

		// 多个商品时,获取每个商品所对应的一组数据，item
		for _, v := range data {
			var item models.MaGoodsActivityDetail
			item.ActivityID = insertID
			item.SalesID = salesID
			item.GoodsID = v.AssocGoodsID
			item.Type = v.Type
			// for _, val := range v.DiscountGoodsInfo {
			DiscountGoodsInfo, _ := json.Marshal(v.DiscountGoodsInfo)
			item.MultiDiscountGoods = string(DiscountGoodsInfo) //json字符串
			// }
			// 写入商品活动详情
			err = db.Model(&models.MaGoodsActivityDetail{}).Create(&item).Error
			if err != nil {
				err = errorx.New("操作失败", -1)
				return
			}
		}

	} else {
		// 编辑
		var updateData models.MaGoodsActivity
		updateData.ActivityName = name // 活动名称
		updateData.SalesID = salesID   // 设备唯一码
		updateData.Status = "1"        // 1 待开始 2进行中 3已结束
		// 只能添加今天以后的数据
		a := carbon.Parse(start_time).Timestamp()
		b := carbon.Parse(end_time).Timestamp()
		updateData.StartTime = strconv.Itoa(int(a))
		updateData.EndTime = strconv.Itoa(int(b))

		// 更新商品活动表
		err = db.Model(&models.MaGoodsActivity{}).Where("id = ?", id).Updates(&updateData).Error
		if err != nil {
			err = errorx.New("更新失败", -1)
			return
		}
		// 删除活动详情表
		db.Model(&models.MaGoodsActivityDetail{}).
			Where("activity_id = ?", id).
			Delete(&models.MaGoodsActivityDetail{})

		// 商品活动详情表
		// 多个商品时,获取每个商品所对应的一组数据，item
		for _, v := range data {
			var item models.MaGoodsActivityDetail
			item.ActivityID = id
			item.SalesID = salesID
			item.GoodsID = v.AssocGoodsID
			item.Type = v.Type
			DiscountGoodsInfo, _ := json.Marshal(v.DiscountGoodsInfo)
			item.MultiDiscountGoods = string(DiscountGoodsInfo) //json字符串
			// 写入商品活动详情
			err = db.Model(&models.MaGoodsActivityDetail{}).Create(&item).Error
			if err != nil {
				err = errorx.New("编辑失败", -1)
				return
			}
		}
	}
	return
}

// SaveGoodsOfMulti 新增编辑多规格商品
func (gs GoodsService) SaveGoodsOfMulti(ctx context.Context, merchantID, id, goodsName string,
	multiGoods []schema.MultiGoodsNew, GoodsDetail, SalesID, RobotName string) (err error) {
	db := mysql.NewDB()
	newDataByte, _ := json.Marshal(&multiGoods)
	OldGoodsData := common.Goods{}.MultiGoodsNewToOld(string(newDataByte))
	multiGoodsBytes, _ := json.Marshal(&OldGoodsData)
	if id == "" { //新增
		var InsertData models.MaGoodsMulti
		InsertData.GoodsName = goodsName
		InsertData.MultiGoods = string(multiGoodsBytes)
		InsertData.GoodsDetail = GoodsDetail
		InsertData.AddTime = time.Now()
		InsertData.SalesID = SalesID
		InsertData.RobotName = RobotName
		err = db.Model(&models.MaGoodsMulti{}).Create(&InsertData).Error
		if err != nil {
			err = errorx.New("操作失败", -1)
			return
		}
	} else { //编辑
		var GoodsInfo models.MaGoodsMulti
		db.Model(&models.MaGoodsMulti{}).
			Where("id = ? ", id).
			Take(&GoodsInfo)
		if GoodsInfo.ID == "" {
			err = errorx.New("商品信息不存在", -1)
			return
		}
		updateErr := db.Model(&models.MaGoodsMulti{}).
			Where("id = ? ", id).
			Updates(map[string]interface{}{
				"goods_name":   goodsName,
				"multi_goods":  string(multiGoodsBytes),
				"goods_detail": GoodsDetail,
				"add_time":     time.Now(),
				"sales_id":     SalesID,
				"robot_name":   RobotName,
			}).Error
		if updateErr != nil {
			err = errorx.New("操作失败", -1)
			return
		}
	}
	return
}

// DelGoodsOfMulti 删除多规格商品
func (gs GoodsService) DelGoodsOfMulti(ctx context.Context, id string) (err error) {
	db := mysql.NewDB()
	if id == "" {
		err = errorx.New("商品id不能为空", -1)
		return
	}
	var GoodsCount int64
	db.Model(&models.MaGoodsMulti{}).
		Where("id = ?", id).
		Count(&GoodsCount)
	if GoodsCount == 0 {
		err = errorx.New("商品信息不存在", -1)
		return
	}
	updateErr := db.Where("id = ?", id).Delete(&models.MaGoodsMulti{}).Error
	if updateErr != nil {
		err = errorx.New("操作失败", -1)
		return
	}
	return
}

// DetailGoodsOfMulti 多规格商品详情
func (gs GoodsService) DetailGoodsOfMulti(ctx context.Context, id string) (data interface{}, err error) {
	db := mysql.NewDB()
	if id == "" {
		err = errorx.New("商品id不能为空", -1)
		return
	}
	var GoodsInfo = models.MaGoodsMulti{}
	db.Model(&models.MaGoodsMulti{}).
		Where("id = ?", id).
		Take(&GoodsInfo)
	addTimeByte, _ := models.DateTime(GoodsInfo.AddTime).MarshalDateTime()
	GoodsInfo.AddTimeFormated = string(addTimeByte)

	GoodsInfo.MultiGoodsFormated = common.Goods{}.MultiGoodsOldToNew(GoodsInfo.MultiGoods)

	return GoodsInfo, nil
}

// 商品下架的机器
type OffShelfRobots struct {
	Type     string `json:"type"`      // 下架类型
	Total    int    `json:"total"`     // 机器总数
	RobotIDs string `json:"robot_ids"` // 机器列表
}

// List 获取商品列表
func (gs GoodsService) List(ctx context.Context, MerchantID string, shopList []string, classID, goodsName string,
	goodsStatus *int, goodsType int, page, limit int) (data interface{}, count int64, err error) {
	db := mysql.NewDB()
	var GoodsList = []struct {
		models.MaGoodsInfo
		ClassName        string           `json:"class_name" gorm:"column:class_name" `
		CornerLabelImage string           `json:"corner_label_image" gorm:"column:corner_label_image" `
		OffShelfRobots   []OffShelfRobots `json:"off_shelf_robots" gorm:"-"`
		Merchant         string           `json:"merchant"`
	}{}
	tx := db.Table(models.MaGoodsInfo{}.TableName() + " as goods").
		Joins("left join " + models.MaGoodsClass{}.TableName() + " as class on class.class_id = goods.class_id").
		Joins("left join " + models.MaGoodsCornerLabel{}.TableName() + " as sub on sub.id = goods.corner_label_id").
		Where("goods.deleted = 0")
	if classID != "" {
		tx.Where("goods.class_id = ?", classID)
	}
	if goodsName != "" {
		tx.Where("goods.goods_name1 like ?", "%"+strings.TrimSpace(goodsName)+"%")
	}
	if goodsStatus != nil {
		tx.Where("goods.goods_status = ?", *goodsStatus)
	}
	if goodsType >= 1 && goodsType <= 8 {
		tx.Where("goods.goods_type = ?", goodsType)
	}
	SystemAdminClient, clientErr := client.GetSystemAdminClient()
	if clientErr != nil {
		return
	}
	// 非管理员时生效
	if MerchantID != "1" {
		// 获取直系商户
		req := &system_admin.FamilyMerchantsReq{
			MerchantId: MerchantID,
		}
		res, err1 := SystemAdminClient.GetFamilyMerchants(ctx, req)
		if err1 != nil {
			return
		}
		var merchantIDs []string
		if len(shopList) > 0 {
			merchantIDs = lo.Intersect(res.MerchantIds, shopList)
		} else {
			merchantIDs = res.MerchantIds
		}
		tx.Where("goods.merchant_id in ?", merchantIDs)
	} else {
		if len(shopList) > 0 {
			tx.Where("goods.merchant_id in ?", shopList)
		}
	}

	tx.Count(&count)
	helper.Gorm{}.Paginate(tx, page, limit).
		Order("goods.merchant_id").
		Select("goods.*,class.class_name,sub.image as corner_label_image").
		Find(&GoodsList)
	if len(GoodsList) == 0 {
		return GoodsList, count, nil
	}
	var merchantIds []string
	for _, v := range GoodsList {
		if !lo.Contains(merchantIds, v.MerchantID) {
			merchantIds = append(merchantIds, v.MerchantID)
		}
	}
	req := &system_admin.MerchantNameReq{
		MerchantIds: merchantIds,
	}
	merchantNameMapRes, err1 := SystemAdminClient.MerchantName(ctx, req)
	if err1 != nil {
		return
	}
	// 获取每个商品的下架机器及数量(查询当前商品的下架数量)
	for index, v := range GoodsList {
		// 下架的商品
		goodsOffShelfRobots, _ := dao.ObjAssociation{}.GetAssociationID(
			ctx,
			dal.Q,
			define.AssociationRobotGoodsOffShelf,
			v.GoodsID,
			"",
		)
		// 下架的推荐商品
		recommendedGoodsOffShelfRobots, _ := dao.ObjAssociation{}.GetAssociationID(
			ctx,
			dal.Q,
			define.AssociationRobotRecommendedGoodsOffShelf,
			v.GoodsID,
			"",
		)
		// 下架的商品广告
		adGoodsOffShelfRobots, _ := dao.ObjAssociation{}.GetAssociationID(
			ctx,
			dal.Q,
			define.AssociationRobotGoodsADOffShelf,
			v.GoodsID,
			"",
		)
		// 下架的机器信息
		GoodsList[index].OffShelfRobots = append(GoodsList[index].OffShelfRobots, OffShelfRobots{
			Type:     "goods",
			Total:    len(goodsOffShelfRobots),
			RobotIDs: strings.Join(goodsOffShelfRobots, ","),
		})
		GoodsList[index].OffShelfRobots = append(GoodsList[index].OffShelfRobots, OffShelfRobots{
			Type:     "recommended_goods",
			Total:    len(recommendedGoodsOffShelfRobots),
			RobotIDs: strings.Join(recommendedGoodsOffShelfRobots, ","),
		})
		GoodsList[index].OffShelfRobots = append(GoodsList[index].OffShelfRobots, OffShelfRobots{
			Type:     "ad_goods",
			Total:    len(adGoodsOffShelfRobots),
			RobotIDs: strings.Join(adGoodsOffShelfRobots, ","),
		})
		// 商户名称
		if merchantName, ok := merchantNameMapRes.MerchantNameMap[v.MerchantID]; ok {
			GoodsList[index].Merchant = merchantName
		}
	}
	return GoodsList, count, nil
}

// Remove 商品删除
func (gs GoodsService) Remove(ctx context.Context, merchantID, goodsIDList string) (err error) {
	db := mysql.NewDB()
	if merchantID != "1" { //非管理员
		cli, err := client.GetSystemAdminClient()
		if err != nil {
			return errorx.New("获取直系商户失败", -1)
		}
		rsp, err := cli.GetFamilyMerchants(ctx, &system_admin.FamilyMerchantsReq{
			MerchantId: merchantID,
		})
		if err != nil || rsp == nil {
			return errorx.New("获取直系商户失败", -1)
		}
		db.Model(&models.MaGoodsInfo{}).
			Where("merchant_id IN ?", rsp.MerchantIds).
			Where("goods_id in (?)", strings.Split(goodsIDList, ",")).
			UpdateColumn("deleted", 1)
	} else {
		db.Model(&models.MaGoodsInfo{}).
			Where("goods_id in (?)", strings.Split(goodsIDList, ",")).
			UpdateColumn("deleted", 1)
	}
	return
}

// Set 商品上下架
func (gs GoodsService) Set(ctx context.Context, merchantID, goodsID string, goodsStatus int) (err error) {
	if goodsStatus != 0 && goodsStatus != 1 && goodsStatus != 2 {
		err = errorx.New("上下架状态错误", -1)
		return
	}

	var count int64
	mysql.NewDB().Model(&models.MaGoodsInfo{}).
		Where("goods_id = ? and deleted = 0 and merchant_id = ?", goodsID, merchantID).
		Count(&count)
	if count == 0 {
		err = errorx.New("商品信息不存在", -1)
		return
	}

	mysql.NewDB().Model(&models.MaGoodsInfo{}).
		Where("merchant_id = ?", merchantID).
		Where("goods_id = ?", goodsID).
		UpdateColumn("goods_status", goodsStatus)
	return
}

// RobotGoodsOffShelf 机器商品下架
func (gs GoodsService) RobotGoodsOffShelf(ctx context.Context, merchantID,
	goodsID string,
	robotIDs []string,
) (err error) {
	if !(dao.Goods{}).Exists(ctx, dal.Q, merchantID, goodsID) {
		return errorx.New("商品不存在", -1)
	}
	if !(dao.Goods{}).HasAuth(ctx, dal.Q, merchantID, goodsID) {
		return errorx.New("无权限", -1)
	}
	// 删除原有关联
	dao.ObjAssociation{}.Delete(ctx, dal.Q, define.AssociationRobotGoodsOffShelf, goodsID, "")
	if len(robotIDs) > 0 {
		// 增加新的关联
		records := []*models.MaObjAssociation{}
		for _, robotID := range robotIDs {
			records = append(records, &models.MaObjAssociation{
				AssociationType: int(define.AssociationRobotGoodsOffShelf),
				ObjID:           goodsID,
				AssociationID:   robotID,
			})
		}
		dao.ObjAssociation{}.Add(ctx, dal.Q, records, 300)
	}
	return
}

// RobotRecommendedGoodsOffShelf 机器推荐的商品下架
func (gs GoodsService) RobotRecommendedGoodsOffShelf(ctx context.Context, merchantID,
	goodsID string,
	robotIDs []string,
) (err error) {
	if !(dao.Goods{}).Exists(ctx, dal.Q, merchantID, goodsID) {
		return errorx.New("商品不存在", -1)
	}
	if !(dao.Goods{}).HasAuth(ctx, dal.Q, merchantID, goodsID) {
		return errorx.New("无权限", -1)
	}
	// 删除原有关联
	dao.ObjAssociation{}.Delete(ctx, dal.Q, define.AssociationRobotRecommendedGoodsOffShelf, goodsID, "")
	if len(robotIDs) > 0 {
		// 增加新的关联
		records := []*models.MaObjAssociation{}
		for _, robotID := range robotIDs {
			records = append(records, &models.MaObjAssociation{
				AssociationType: int(define.AssociationRobotRecommendedGoodsOffShelf),
				ObjID:           goodsID,
				AssociationID:   robotID,
			})
		}
		dao.ObjAssociation{}.Add(ctx, dal.Q, records, 300)
	}
	return
}

// RobotAdGoodsOffShelf 机器商品广告下架
func (gs GoodsService) RobotGoodsADOffShelf(ctx context.Context, merchantID,
	goodsID string,
	robotIDs []string,
) (err error) {
	if !(dao.Goods{}).Exists(ctx, dal.Q, merchantID, goodsID) {
		return errorx.New("商品不存在", -1)
	}
	if !(dao.Goods{}).HasAuth(ctx, dal.Q, merchantID, goodsID) {
		return errorx.New("无权限", -1)
	}
	// 删除原有关联
	dao.ObjAssociation{}.Delete(ctx, dal.Q, define.AssociationRobotGoodsADOffShelf, goodsID, "")
	if len(robotIDs) > 0 {
		// 增加新的关联
		records := []*models.MaObjAssociation{}
		for _, robotID := range robotIDs {
			records = append(records, &models.MaObjAssociation{
				AssociationType: int(define.AssociationRobotGoodsADOffShelf),
				ObjID:           goodsID,
				AssociationID:   robotID,
			})
		}
		dao.ObjAssociation{}.Add(ctx, dal.Q, records, 300)
	}
	return
}

type GoodsOptions struct {
	GoodsID   string `json:"goods_id"`
	GoodsName string `json:"goods_name"`
}

func (gs GoodsService) Options(ctx context.Context, merchantID string, shopList []string,
	provinceID, cityID, districtID, locationID, robotID, goodsName string, page, limit int) (
	res []GoodsOptions, count int64, err error,
) {
	var filterRobotID []string
	if robotID != "" {
		filterRobotID = strings.Split(robotID, ",")
	}
	var filterLocation []string
	if locationID != "" {
		filterLocation = strings.Split(locationID, ",")
	}
	var filterMerchants = []string{} // 归属商户
	if merchantID != "1" {
		SystemAdminClient, clientErr := client.GetSystemAdminClient()
		if clientErr != nil {
			return
		}
		// 获取直系商户
		req := &system_admin.FamilyMerchantsReq{
			MerchantId: merchantID,
		}
		rsp, err1 := SystemAdminClient.GetFamilyMerchants(ctx, req)
		if err1 != nil {
			return
		}
		if len(shopList) > 0 {
			filterMerchants = lo.Intersect(rsp.MerchantIds, shopList)
		} else {
			filterMerchants = rsp.MerchantIds
		}
	} else {
		if len(shopList) > 0 {
			filterMerchants = shopList
		}
	}
	// 确定商户机器
	DeviceAdminClient, clientErr := client.GetDeviceAdminClient()
	if clientErr != nil {
		return
	}
	req := &devicec.DeviceListReq{
		ProvinceId: provinceID, // 省
		CityId:     cityID,     // 市
		DistrictId: districtID, // 区
	}
	rsp, err2 := DeviceAdminClient.DeviceList(ctx, req)
	if err2 != nil {
		return
	}
	var validRobots = []string{} // 归属机器
	for _, v := range rsp.List {
		if len(filterLocation) > 0 && !lo.Contains(filterLocation, v.LocationId) {
			continue
		}
		if len(filterMerchants) > 0 && !lo.Contains(filterMerchants, v.MerchantId) {
			continue
		}
		if len(filterRobotID) > 0 && !lo.Contains(filterRobotID, v.RobotId) {
			continue
		}
		validRobots = append(validRobots, v.RobotId)
	}
	if len(validRobots) == 0 {
		return
	}

	var goodsIDs []string
	mysql.NewDB().Model(&models.MaRobotSalesInfo{}).
		Where("robot_name in ?", validRobots).
		Pluck("distinct(goods_id)", &goodsIDs)

	if len(goodsIDs) == 0 {
		return
	}
	tx := mysql.NewDB().Model(&models.MaGoodsInfo{}).
		Where("goods_id in ?", goodsIDs)
	// 商品名称筛选
	if goodsName != "" {
		tx = tx.Where("goods_name1 like ?", "%"+goodsName+"%")
	}
	tx.Select("goods_id,goods_name1 as goods_name").
		Order("goods_id").
		Find(&res)
	return res, int64(len(res)), nil
}

// 设置商品活动
func (gs GoodsService) LogList(ctx context.Context) (err error) {
	return nil
}

func (gs GoodsService) LogDetail(ctx context.Context, id int64) (err error) {
	return nil
}

func (gs GoodsService) VerifyGoodsGuideParams(goodsGuideType define.GoodsGuideType,
	goodsGuideURL string, shareCodeType define.ShareCodeType, shareCode string) error {
	if goodsGuideType != define.GoodsGuideTypeNil && goodsGuideType != define.GoodsGuideTypeQR && goodsGuideType != define.GoodsGuideTypeShareCode {
		return errorx.New("导流类型不正确", -1)
	}
	if goodsGuideType == define.GoodsGuideTypeQR {
		if goodsGuideURL == "" {
			return errorx.New("导流URL不能为空", -1)
		}
	} else if goodsGuideType == define.GoodsGuideTypeShareCode {
		if shareCodeType == "" {
			return errorx.New("导流分享码类型不能为空", -1)
		}
		if shareCode == "" {
			return errorx.New("导流分享码不能为空", -1)
		}
	}

	return nil
}
